package com.example.dynamicschedule.task;


import com.alibaba.fastjson.JSON;
import com.example.dynamicschedule.bean.*;
import com.example.dynamicschedule.dao.*;
import com.example.dynamicschedule.utils.DateUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Component
public class CreditOutcompanyCommissionTask {
    static Logger log = Logger.getLogger(CreditOutcompanyCommissionTask.class);
    @Autowired
    private CkCreditOutCompanyDataLogMapper ckCreditOutCompanyDataLogMapper;
    @Autowired
    private CkCreditRecoverMoneyMapper ckCreditRecoverMoneyMapper;
    @Autowired
    private CkCreditOutcompanyCommissionMapper ckCreditOutcompanyCommissionMapper;
    @Autowired
    private CkCreditOutcompanyFixedAgentMapper ckCreditOutcompanyFixedAgentMapper;
    @Autowired
    private DateUtils dateUtils;
    @Autowired
    private CkOutsourcingCompanyRateMapper ckOutsourcingCompanyRateMapper;

    /**
     * 代理模式为佣金和固定代理的佣金计算
     */
    @Transactional
    public void CreditOutcompanyCommissionTask() {
        log.info("佣金计算-----------------------------------------------------开始");
        log.info("佣金计算---------------获取案件和委外公司信息-----------------开始");
        String likeBatchNumber = null;
        String nowDayStr = dateUtils.getNowDayStr();
        if ("01".equalsIgnoreCase(nowDayStr)) {
            likeBatchNumber = dateUtils.getPreLikeBatchNumber();
        } else {
            likeBatchNumber = dateUtils.getLikeBatchNumber();
        }
        List<CkCreditOutCompanyDataLog> ckCreditOutCompanyDataLogList = ckCreditOutCompanyDataLogMapper.selectByBatchNumberList(likeBatchNumber);
        if (CollectionUtils.isNotEmpty(ckCreditOutCompanyDataLogList)) {
            log.info("佣金计算---------------获取案件和委外公司信息-----------------数据为" + JSON.toJSONString(ckCreditOutCompanyDataLogList));
            Map<String, CkCreditOutCompanyDataLog> cardNumberMap = new HashMap<>();
            List<String> cardNumbers = new ArrayList<>();
            Set<String> outCompanyNames = new HashSet<>();
            for (CkCreditOutCompanyDataLog ckCreditOutCompanyDataLog : ckCreditOutCompanyDataLogList) {
                String cardNumber = ckCreditOutCompanyDataLog.getCardNumber();
                String outCompanyName = ckCreditOutCompanyDataLog.getOutCompanyName();
                cardNumberMap.put(cardNumber, ckCreditOutCompanyDataLog);
                cardNumbers.add(cardNumber);
                outCompanyNames.add(outCompanyName);
            }
            log.info("佣金计算---------------获取案件和委外公司信息-----------------结束");
            log.info("佣金计算---------------获取委外公司佣金比率-----------------开始");
            List<CkOutsourcingCompanyRate> ckOutsourcingCompanyRates = ckOutsourcingCompanyRateMapper.selectByOutCompanyNames(outCompanyNames);
            Map<String, List<CkOutsourcingCompanyRate>> ckOutsourcingCompanyMap = new HashMap<>();
            for (CkOutsourcingCompanyRate ckOutsourcingCompany : ckOutsourcingCompanyRates) {
                String outsourcingCompany = ckOutsourcingCompany.getCompanyName();
                List<CkOutsourcingCompanyRate> ckOutsourcingCompanyRateList = null;
                if (ckOutsourcingCompanyMap.get(outsourcingCompany) != null) {
                    ckOutsourcingCompanyRateList = ckOutsourcingCompanyMap.get(outsourcingCompany);
                } else {
                    ckOutsourcingCompanyRateList = new ArrayList<>();
                }
                ckOutsourcingCompanyRateList.add(ckOutsourcingCompany);
                ckOutsourcingCompanyMap.put(outsourcingCompany, ckOutsourcingCompanyRateList);
            }
            log.info("佣金计算---------------获取委外公司佣金比率-----------------结束");
            log.info("佣金计算---------------获取还款数据-----------------开始");
            Map<String, Object> params = new HashMap<>();
            params.put("batch", dateUtils.getLikeBatchNumber());
            params.put("cardNumbers", cardNumbers);
            List<CkCreditRecoverMoney> ckCreditRecoverMonies = ckCreditRecoverMoneyMapper.selectByCardNumbersAndBatchNumber(params);
            List<CkCreditOutcompanyCommission> ckCreditOutcompanyCommissions = new ArrayList<>();
            List<CkCreditOutcompanyFixedAgent> ckCreditOutcompanyFixedAgents = new ArrayList<>();
            log.info("佣金计算---------------获取还款数据-----------------结束");
            log.info("佣金计算---------------开始计算佣金-----------------开始");
            if (CollectionUtils.isNotEmpty(ckCreditRecoverMonies)) {
                for (CkCreditRecoverMoney ckCreditRecoverMony : ckCreditRecoverMonies) {
                    //卡号
                    String cardNumber = ckCreditRecoverMony.getCardNumber();
                    //批次号
                    String batchNumber = ckCreditRecoverMony.getBatchNumber();
                    //还款金额
                    Double repaymentAmount = ckCreditRecoverMony.getRepaymentAmount();
                    //案件号
                    String serialNumber = ckCreditRecoverMony.getSerialNumber();
                    //还款金额
                    String repaymentDate = ckCreditRecoverMony.getRepaymentDate();
                    //逾期金额
                    Double overdueArrears = ckCreditRecoverMony.getOverdueArrears();
                    //委外案件
                    CkCreditOutCompanyDataLog ckCreditOutCompanyDataLog = cardNumberMap.get(cardNumber);
                    //委外公司名称
                    String outCompanyName = ckCreditOutCompanyDataLog.getOutCompanyName();
                    //委外公司
                    List<CkOutsourcingCompanyRate> ckOutsourcingCompanyRateList = ckOutsourcingCompanyMap.get(outCompanyName);
                    //期数
                    String numberOfOverduePeriods = ckCreditOutCompanyDataLog.getNumberOfOverduePeriods();
                    //身份证号
                    String identificationNumber = ckCreditOutCompanyDataLog.getIdentificationNumber();
                    //卡种
                    String allotType = ckCreditOutCompanyDataLog.getAllotType();
                    Map<String, String> rateMap = getRate(numberOfOverduePeriods, ckOutsourcingCompanyRateList);
                    String checkModel = rateMap.get("checkModel");
                    if ("1".equalsIgnoreCase(checkModel)) {
                        String agencyReturnRate = rateMap.get("agencyReturnRate");
                        if (StringUtils.isNotEmpty(agencyReturnRate)) {
                            Double rate = Double.valueOf(agencyReturnRate);
                            Double d = repaymentAmount;
                            if (repaymentAmount > overdueArrears) {
                                d = overdueArrears;
                            }
                            if (rate != null && rate > 0) {
                                Double commission = new BigDecimal(d).multiply(new BigDecimal(rate)).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                                CkCreditOutcompanyFixedAgent ckCreditOutcompanyFixedAgent = new CkCreditOutcompanyFixedAgent();
                                ckCreditOutcompanyFixedAgent.setBatchNumber(batchNumber);
                                ckCreditOutcompanyFixedAgent.setSerialNumber(serialNumber);
                                ckCreditOutcompanyFixedAgent.setCardNumber(cardNumber);
                                ckCreditOutcompanyFixedAgent.setCardType(allotType);
                                ckCreditOutcompanyFixedAgent.setIdentificationNumber(identificationNumber);
                                ckCreditOutcompanyFixedAgent.setOutMoney(overdueArrears);
                                ckCreditOutcompanyFixedAgent.setRecoverMoney(repaymentAmount);
                                ckCreditOutcompanyFixedAgent.setRate(rate);
                                ckCreditOutcompanyFixedAgent.setCommission(commission);
                                ckCreditOutcompanyFixedAgent.setRepaymentDate(repaymentDate);
                                ckCreditOutcompanyFixedAgent.setOutCompant(outCompanyName);
                                ckCreditOutcompanyFixedAgents.add(ckCreditOutcompanyFixedAgent);
                            } else {
                                log.info("佣金计算---------------佣金比率不正确-----------------佣金比率为" + d+";委外公司为"+outCompanyName);
                            }
                        } else {
                            log.info("佣金计算---------------佣金比率为空-----------------委外公司名称为"+outCompanyName );
                        }
                        log.info("佣金计算---------------计算固定代理费开始-----------------结束");
                    } else if ("2".equalsIgnoreCase(checkModel)) {
                        String levelRate = rateMap.get("levelRate");
                        if (StringUtils.isNotEmpty(levelRate)) {
                            Double rate = Double.valueOf(levelRate);
                            Double d = repaymentAmount;
                            if (repaymentAmount > overdueArrears) {
                                d = overdueArrears;
                            }
                            //佣金
                            if (rate != null && rate > 0) {
                                Double commission = new BigDecimal(d).multiply(new BigDecimal(rate)).doubleValue();
                                CkCreditOutcompanyCommission ckCreditOutcompanyCommission = new CkCreditOutcompanyCommission();
                                ckCreditOutcompanyCommission.setBatchNumber(batchNumber);
                                ckCreditOutcompanyCommission.setSerialNumber(serialNumber);
                                ckCreditOutcompanyCommission.setCardNumber(cardNumber);
                                ckCreditOutcompanyCommission.setCardType(allotType);
                                ckCreditOutcompanyCommission.setIdentificationNumber(identificationNumber);
                                ckCreditOutcompanyCommission.setOutMoney(overdueArrears);
                                ckCreditOutcompanyCommission.setRecoverMoney(repaymentAmount);
                                ckCreditOutcompanyCommission.setRate(rate);
                                ckCreditOutcompanyCommission.setCommission(commission);
                                ckCreditOutcompanyCommission.setRepaymentDate(repaymentDate);
                                ckCreditOutcompanyCommission.setOutCompant(outCompanyName);
                                ckCreditOutcompanyCommissions.add(ckCreditOutcompanyCommission);
                            } else {
                                log.info("佣金计算---------------佣金比率不正确-----------------佣金比率为" + d+";委外公司为"+outCompanyName);
                            }
                            log.info("佣金计算---------------计算回佣比率开始-----------------结束");
                        } else {
                            log.info("佣金计算---------------佣金比率为空-----------------委外公司名称为"+outCompanyName );
                        }
                    } else {
                        log.info("佣金计算---------------对账模式为其他-----------------" );
                    }
                }
                log.info("佣金计算---------------保存对账模式为回佣比率类-----------------开始" );
                if (CollectionUtils.isNotEmpty(ckCreditOutcompanyCommissions)) {
                    ckCreditOutcompanyCommissionMapper.insertForEach(ckCreditOutcompanyCommissions);
                }
                log.info("佣金计算---------------保存对账模式为回佣比率类-----------------结束" );
                log.info("佣金计算---------------保存对账模式为固定代理类-----------------开始" );
                if (CollectionUtils.isNotEmpty(ckCreditOutcompanyFixedAgents)) {
                    ckCreditOutcompanyFixedAgentMapper.insertForEach(ckCreditOutcompanyFixedAgents);
                }
                log.info("佣金计算---------------保存对账模式为固定代理类-----------------结束" );
                log.info("佣金计算---------------开始计算佣金-----------------结束");
                log.info("佣金计算-----------------------------------------------------结束");
            } else {
                log.info("佣金计算---------------获取还款数据-----------------为空");
            }
            log.info("佣金计算---------------获取还款数据-----------------结束");
        } else {
            log.info("佣金计算---------------获取案件和委外公司信息数据为空-----------------结束");
            log.info("佣金计算-----------------------------------------------------结束");
        }
    }


    /**
     * 获取佣金比率
     *
     * @param numberOfOverduePeriods
     * @param ckOutsourcingCompanyRateList
     * @return
     */
    private Map<String, String> getRate(String numberOfOverduePeriods, List<CkOutsourcingCompanyRate> ckOutsourcingCompanyRateList) {
        Map<String, String> resultMap = new HashMap<>();
        for (CkOutsourcingCompanyRate ckOutsourcingCompanyRate : ckOutsourcingCompanyRateList) {
            //对账模式
            String checkModel = ckOutsourcingCompanyRate.getCheckModel();
            resultMap.put("checkModel", checkModel);
            //逾期等级
            String levelName = ckOutsourcingCompanyRate.getLevelName();
            resultMap.put("levelName", levelName);
            //判断对账模式为回佣时的回佣比率
            if (Integer.valueOf(numberOfOverduePeriods) > 6) {
                numberOfOverduePeriods="7";
            }
            if (StringUtils.isNotEmpty(numberOfOverduePeriods)) {
                if (numberOfOverduePeriods.equalsIgnoreCase(levelName)) {
                Double comRate = ckOutsourcingCompanyRate.getComRate();
                resultMap.put("levelRate", String.valueOf(comRate));
            }
        }
            //固定代理类比率
            Double agencyReturnRate = ckOutsourcingCompanyRate.getAgencyReturnRate();
            resultMap.put("agencyReturnRate", String.valueOf(agencyReturnRate));
        }
        return resultMap;
    }
}
